package org.lex.keytool.ui;

import java.util.EventListener;

import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import org.lex.collection.tree.ITreeNode;
import org.lex.keytool.core.service.TaskService;
import org.lex.keytool.core.task.Task;
import org.lex.keytool.ui.builder.MenuTreeBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MenuTree extends JTree {
	private MenuChangeListener menuChangeListener = null;
	private Logger log = LoggerFactory.getLogger(MenuTree.class);

	public MenuTree() {
		super(new MenuTreeBuilder().buildMenuTreeModel());
		this.getSelectionModel().addTreeSelectionListener(new SelectionHandler());
		this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
	}

	public void addMenuChangeListener(MenuChangeListener l) {
		this.menuChangeListener = l;
	}

	protected void fireMenuChanged(Class<? extends Task> taskClass) {
		if (null != menuChangeListener) {
			menuChangeListener.selectedMenuChanged(taskClass);
		}
	}

	private class SelectionHandler implements TreeSelectionListener {
		@Override
		public void valueChanged(TreeSelectionEvent e) {
			TreePath path = e.getPath();
			ITreeNode last = (ITreeNode) path.getLastPathComponent();
			log.debug("tree selected node: [" + last + "] " + (last.hasChildren() ? "is NOT" : "IS") + " leaf node");
			String taskName = this.getSelectedTaskName(path);
			Class<? extends Task> clz = TaskService.getInstance().getTaskClass(taskName);
			fireMenuChanged(clz);
		}

		private String getSelectedTaskName(TreePath path) {
			StringBuilder buf = new StringBuilder();
			Object[] elements = path.getPath();
			for (int i = 1, n = elements.length; i < n; i++) {
				ITreeNode node = (ITreeNode) elements[i];
				buf.append(node.getData());
				if (i < n - 1) {
					buf.append(".");
				}
			}
			String taskName = buf.toString();
			log.info("selected taskName=" + taskName);
			return taskName;
		}
	}

	public static interface MenuChangeListener extends EventListener {
		public void selectedMenuChanged(Class<? extends Task> taskClass);
	}
}
